package com.eight.service;

import com.eight.feign.AdminFeign;
import com.eight.feign.PermissionFeign;
import com.eight.pojo.SysAdmin;
import com.eight.pojo.SysMenu;
import com.eight.vo.ComResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 此类用于从数据库中加载出Admin的具体信息然后交予SpringSecurity
 * @Author: Van.Planifolia
 * @CreateTime: 2023-02-23  11:25
 * @Version: 1.0
 */
// 当使用 Service注解的时候尽量设置value值来标注从而实现 byName注入
@Service("userService")
public class UserService implements UserDetailsService {
    @Autowired
    private AdminFeign adminFeign;
    @Autowired
    private PermissionFeign permissionFeign;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 加载用户信息的方法，这里会接收到前面传递过来的username
     *
     * @param s 用户的姓名
     * @return 要载入security的具体用户信息
     * @throws UsernameNotFoundException 找不到用户名异常
     */
    @Override

    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        // 先调用费恩从Admin组件中找到对应的实体
        SysAdmin admin = adminFeign.getAdminByName(s);
        // 找到之后我们根据用户名去查询用户的权限，然后把用户信息以及权限塞进去
        User user;
        if (admin != null) {
            // 获取权限并且制作成真实的权限List
            List<SysMenu> permission = permissionFeign.getPermissionByName(admin.getAdminUsername());
            // stream会遍历权限中的全部信息并且过滤出有权限的信息放进去
            List<SimpleGrantedAuthority> realPermission = permission.stream().filter(e -> StringUtils.hasText(e.getPerms())).map(e -> new SimpleGrantedAuthority(e.getPerms())).collect(Collectors.toList());
            user = new User(admin.getAdminUsername(), admin.getAdminPassword(), realPermission);
        } else {
            throw new UsernameNotFoundException("找不到用户信息");
        }
        return user;
    }

    /**
     * 用户登出的方法
     *
     * @return 登出的结果
     */
    public ComResult logout(HttpServletRequest request) {
        // 拿到token
        String token = request.getHeader("token");
        // 删除token
        return Boolean.TRUE.equals(redisTemplate.delete(token)) ? new ComResult(2000, "登出成功") : new ComResult(5000, "登出失败");
    }
}
